package es.uc3m.setichat.android;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import es.uc3m.setichat.android.activity.SeTIChatActivity;
import es.uc3m.setichat.android.activity.SeTIChatConversationActivity;
import es.uc3m.setichat.android.activity.SeTIChatLoginActivity;
import es.uc3m.setichat.clases.SeTIChatMessage;

/**
 * Application service that runs locally in the same process as the application.
 * 
 * Services can perform long-running operations in the background and does not provide a user interface. 
 * They are also very useful to perform interprocess communication (IPC). 
 * For example, a service might handle network transactions :), content providers, etc. ;)
 * 
 * When any SeTI chat is received in the service {@link NotificationManager} is
 * used to interact with the user, rather than doing something more disruptive
 * such as calling startActivity().
 * 
 * Note: For more details on how Services works, see Androids doc. and sample
 * code. http://developer.android.com/reference/android/app/Service.html
 * 
 * @author Guillermo Suarez de Tangil <guillermo.suarez.tangil@uc3m.es>
 * @author Jorge Blasco Alis <jbalis@inf.uc3m.es>
 */

public class SeTIChatService extends Service {
	
	private NotificationManager mNM;
	// Unique Identification Number for the Notification.
	// We use it on Notification start, and to cancel it.
	private int NOTIFICATION = R.string.seti_chat_service_started;

	private boolean DEBUG = false;
	
	public SeTIChatXMPPController xmppController = null;
	
	public SeTIChatContactsController contactsController = null;
	
	public HashMap<String,String> ids_sends;
	
	
	public String email;
	public String psw;
	public String mobil;
	public String nick;
	
	/**
	 * Class for clients to access.
	 */
	public class LocalBinder extends Binder {
		public SeTIChatService getService() {
			return SeTIChatService.this;
		}
	}

	public boolean getDebug(){ 
		return DEBUG;
	}
	
	
	
	@Override
	public void onCreate() {
		
		
		
		Log.d("SeTIChatService", "debug: " +  getText(R.string.debug).toString());
		DEBUG  = getText(R.string.debug).toString().compareTo("true") == 0?true:false;
		if(DEBUG) Log.d("SeTIChatService", "Starting SeTIChat Service...");
		
		
		
		/* ******************************************************* * 
		 * Called by the system when the service is first created. *
		 *  - A connection to the XMPP server will be established. *
		 *  - A connection to the DB will be established           *
		 *  - User settings will be set                            *
		 *  - CA certificate will be loaded                        *
		 * ******************************************************* */
		ids_sends = new HashMap<String, String>();
		
		contactsController = new SeTIChatContactsController(getContentResolver(), getBaseContext(),xmppController,DEBUG);
		
		SeTIChatSQLiteHelper setiDB = new SeTIChatSQLiteHelper(getBaseContext(), "BBDDSetichat", null, SeTIChatSQLiteHelper.SQL_VERSION);
		
		SQLiteDatabase db = setiDB.getReadableDatabase();
        Cursor c = db.query("login",new String[]{"mobil","email","psw","nick"},null, null,null,null,null);
        
        SeTIChatCertificatesController.context = this;
        
    	if(c.moveToFirst()){
    		SeTIChatCertificatesController.initPrivateKey();
    		email 			= c.getString(1);
    		psw 			= c.getString(2);
    		mobil 			= c.getString(0);
    		xmppController 	= new SeTIChatXMPPController(DEBUG,email,psw,this,false);
    		c.close();
            db.close();
            setiDB.close();
    	}else{
    		c.close();
            db.close();
            setiDB.close();
            
    		Intent intent = new Intent();
    		intent.setClass(getBaseContext(), SeTIChatLoginActivity.class);
    		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    		startActivity(intent);
    	}
    	
		// Instantiate NotificationManager and display a notification 
		mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
				
		showNotification(null,null,null); // We put an icon in the status bar.
	}
	
	public void repaintChat(String mobile){
		Intent intent = new Intent();
		intent.setClass(getBaseContext(), SeTIChatLoginActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(intent);
	}
	
	public void showError(String error){
		Toast.makeText(SeTIChatService.this, error,Toast.LENGTH_SHORT).show();
	}
	
	public void signup(){
		SeTIChatMessageController msController = new SeTIChatMessageController(getBaseContext());
		msController.insertLogin(email,mobil,psw,nick);
		
        SeTIChatXMLController xml = new SeTIChatXMLController();
        SeTIChatXMLController.mobile = mobil;
        String random_id = xml.generateRandomID();
        xmppController.sendMessage(xml.createSignUp(random_id, nick), random_id,"signup");
	}
	
	public void initXMPP(){
		/* *********************** *
		 * If this is the first time the user starts the application: 
		 *  - Send sing up
		 *  - Download certificates (user and server)
		 *  - Send Connection Message
		 * *********************** */
		//send message connection
		SeTIChatXMLController xml = new SeTIChatXMLController();
		SeTIChatSQLiteHelper setiDB = new SeTIChatSQLiteHelper(getBaseContext(), "BBDDSetichat", null, SeTIChatSQLiteHelper.SQL_VERSION);
		SQLiteDatabase db = setiDB.getReadableDatabase();
        Cursor c = db.query("login",new String[]{"mobil","email","psw","nick"},null, null,null,null,null);
        if(c.moveToFirst()){
    		email 			= c.getString(1);
    		psw 			= c.getString(2);
    		mobil 			= c.getString(0);
        }
        c.close();
        db.close();
        setiDB.close();
       
		SeTIChatXMLController.mobile = mobil;
		String random_id = xml.generateRandomID();
		xmppController.sendMessage(xml.createConnection(random_id),random_id,"connection");
		
		/* ******************************************* * 
		 * Start the Contact protocol                  *
		 *  - get SeTIChat contacts from data base     *
		 *  - get SeTIChat new contacts from server    *
		 * ******************************************* */
		//send contactRequest
		contactsController = new SeTIChatContactsController(getContentResolver(), getBaseContext(),xmppController,DEBUG);
		contactsController.getContactsInitials();
	}
	
	private String emulateStudentMobile(String nia_stud_1, String nia_stud_2, String nia_stud_3) {
		
		if(nia_stud_1 == null || nia_stud_1.length()!=9){
			throw new IllegalArgumentException("Student NIA is not valid" + nia_stud_1);
		}
		
		if(nia_stud_2 != null ){
			
			if(nia_stud_2.length()!=9){
				throw new IllegalArgumentException("Student NIA is not valid" + nia_stud_2);
			}else
				nia_stud_2 = "." + nia_stud_2;
			
		}
		
		if(nia_stud_3 != null ){
				
			if(nia_stud_3.length()!=9){
				throw new IllegalArgumentException("Student NIA is not valid" + nia_stud_3);
			}else
				nia_stud_3 = "." + nia_stud_3;
			
		}

		return nia_stud_1 + nia_stud_2 + nia_stud_3;
		
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		/*
		 * Called by the system every time a client explicitly starts the
		 * service by calling startService(Intent), providing the arguments it
		 * supplied and a unique integer token representing the start request.
		 */
		if(DEBUG) Log.d("SeTIChatService", "Received start id " + startId + ", flag: " + flags + ": " + intent);

		// We want this service to continue running until it is explicitly
		// stopped,
		return START_STICKY; // so return sticky.
	}

	@Override
	public void onDestroy() {
		
		if(DEBUG)
			Log.d("SeTIChatService", "Destroying Service...");
		
		// Cancel the persistent notification.
		mNM.cancel(NOTIFICATION);
		
		//Close and drestroy all the objects
        //...
		
		// Tell the user we stopped.
		Toast.makeText(this, R.string.seti_chat_service_stopped,
				Toast.LENGTH_SHORT).show();
	}

	@Override
	public IBinder onBind(Intent intent) {
		if(DEBUG)
			Log.d("SeTIChatService", "Binding Service to an Activity...");
		return mBinder;
	}

	// This is the object that receives interactions from clients.
	private final IBinder mBinder = new LocalBinder();

	/**
	 * Show a notification while this service is running.
	 */
	public void showNotification(String text_string,String title_string,String mobile) {
		// Text for the ticker and the expanded notification
		CharSequence text = getText(R.string.seti_chat_service_started);
		
		if(title_string != null){
			text = title_string;
		}

		// Set the icon, scrolling text and timestamp
		Notification notification = new Notification(R.drawable.setichat,
				text, System.currentTimeMillis());

		// The PendingIntent to launch our SeTI Chat activity if the user
		// selects this notification
		// Here could also be launched the conversation related to the notification
		Intent intent = null;
		if(mobile != null){
			intent = new Intent(this, SeTIChatConversationActivity.class);
			intent.putExtra("mobile",mobile);
		}else{
			intent = new Intent(this, SeTIChatActivity.class);
		}
		
		
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,intent, 0);

		// A preview of the message could be also set here ;)
		//...
		
		// Set the info for the views that show in the notification panel.
		String title = getText(R.string.seti_chat_service_label).toString();
		
		if(title_string != null){
			title = title_string;
		}
		if(text_string != null){
			text = text_string;
		}
		notification.setLatestEventInfo(this,title, text, contentIntent);

		// Send the notification.
		mNM.notify(NOTIFICATION, notification);
	}
		
}
